<?php
/**
 * @author andkirby@gmail.com
 */

class App_NSTree extends Cruiser_NSTree
{
    /**
     * Id of root item
     * 
     * @var int
     */
    protected $_rootId;
    
    /**
     * Total count of gotted tree
     * 
     * @var int
     */
    protected $_countTotal;
    
    function __construct($config)
    {
        parent::__construct($config);
        $this->_rootData = $config['rootData'];
    }
    
    /**
     * Get root id with "where" logic
     * 
     * @param array $con
     * @return int
     */
    public function getRootId()
    {
        $con = $this->_condition;
        if ($this->_rootId == null) {
            if (! is_array($con) || empty($con)) {
                throw new Cruiser_NSTree_Exception('The condition variable should be an array and not empty');
            }
            foreach ($con as $key => $val)
                $conSql["`" . $key . "` = ?"] = $val;
            $data = $this->_table->fetchRow($conSql);
            if ($data == null) {
                // create root
                $columns = array(
                    $this->_left 	=> 1,
                    $this->_right 	=> 2,
                    $this->_level 	=> 0
                );
                if ($this->_rootData) {
                    foreach ($this->_rootData as $key => $val)
                        $columns[$key] = $val;
                }
                foreach ($con as $key => $val)
                    $columns[$key] = $val;
                $this->_rootId = $this->_table->insert($columns);
            } else {
                $this->_rootId = $data->{$this->_primary};
            }
        }
        return $this->_rootId;
    }
    
    /**
     * Get data tree
     * 
     * @param int $id
     * @return array
     */
    function getTree($id, $params = array())
    {
        $result = $this->select($id, App_NSTree::AXIS_DESCENDANT_OR_SELF, $params);
        if ($result instanceof Cruiser_NSTree_Nodeset) {
            $result = $this->_generateTree($result);
        }
        return $result;
    }
    
    /**
     * Get childrens tree nodes in array
     * 
     * @param Cruiser_NSTree_Nodeset $nodes
     * @return array|gereated_Tree 
     */
    private function _generateTree ($nodes, $level = 0)
    {
        $dataTree = array();
        if ($level == 0) {
            $this->_countTotal = 0;
        }
        while (($nodeCurrent = $nodes->current()) !== false) {
            $this->_countTotal++;
            $key = $nodeCurrent->getPrimary();
            $data = $nodeCurrent->toArray();
            $dataTree[$key] = $data;
            if ($nodes->hasChildren()) {
                $dataTree[$key]['childs'] = $this->_generateTree($nodes->getChildren(), $nodeCurrent->getLevel() + 1);
            }
            $nodes->next();
        }
        return $dataTree;
    }
    
    /**
     * Get total count after getting tree
     * 
     * @return unknown_type
     */
    function getCountTotal()
    {
        return $this->_countTotal;
    }
    
    /**
     * Add child to parent node
     * 
     * @param $parentId     Id of parent node. If NULL then used rood node
     * @param $message      Message
     * @return Cruiser_NSTree_Node
     */
    function add($data, $parentId = null)
    {
        if (! $parentId) {
            $parentId = $this->getRootId();
        }
        $data = $this->_addConditionData($data);
        $node = $this->appendChild((int) $parentId, $data);
        return $node;
    }
    
    /**
     * Add required data from condition
     * 
     * @param array $data
     * @return array
     */
    private function _addConditionData($data)
    {
        if (! empty($this->_condition)) {
            foreach ($this->_condition as $key => $val) {
                $data[$key] = $val;
            }
        }
        return $data;
    }
}
